package com.erbantou.filemanage.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;

@Configuration
public class SecurityConfig {

    private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
    @Value("${spring.security.user.name:admin}")
    private String username;
    @Value("${spring.security.user.password:5hI5hI9IWIwA}")
    private String password;
    @Value("${spring.security.user.role:USER}")
    private String role;

    public SecurityConfig(CustomAuthenticationEntryPoint customAuthenticationEntryPoint) {
        this.customAuthenticationEntryPoint = customAuthenticationEntryPoint;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 定义 SimpleUrlLogoutSuccessHandler 并设置重定向 URL
        SimpleUrlLogoutSuccessHandler logoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
        logoutSuccessHandler.setDefaultTargetUrl("/login");

        // 允许所有用户进行注销
        http
                .authorizeHttpRequests(authorize -> authorize
                        // 允许对 WebSocket 端点的访问
                        .requestMatchers("/ws/**").permitAll()
                        // 允许对静态资源、错误页面等的访问
                        .requestMatchers("/", "/login", "/css/**", "/js/**", "/resources",
                                "/resources/download/**", "/favicon.ico", "/public/**", "/error",
                                "/api/resources/list", "/api/resources/download"
                        )
                        .permitAll()
                        // 其他所有请求需要认证
                        .anyRequest().authenticated()
                )
                .formLogin(formLogin -> formLogin
                        // 指定自定义登录页面的路径
                        .loginPage("/login")
                        // 允许所有用户访问登录页面和其他公共资源
                        .permitAll()
                        // 设置登录成功后的默认跳转页面
                        .defaultSuccessUrl("/resources", true)
                )
                .logout(logout -> logout
                        // 处理注销的 URL
                        .logoutUrl("/logout")
                        // 注销成功后重定向到登录页面
                        .logoutSuccessHandler(logoutSuccessHandler)
                        .permitAll()
                )
                .exceptionHandling(exceptionHandling -> exceptionHandling
                        // 使用自定义的 EntryPoint
                        .authenticationEntryPoint(customAuthenticationEntryPoint)
                )
                // 启用 HTTP Basic 认证
                .httpBasic(Customizer.withDefaults())
                // 在开发过程中可以禁用CSRF保护，但生产环境中应启用
                .csrf(AbstractHttpConfigurer::disable);


        // 如果你需要启用 CSRF 保护，可以使用以下配置，而不是完全禁用
        // .csrf(csrf -> csrf.ignoringRequestMatchers("/ws/**", "/ws/**/**"));
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 配置一个内存中的用户存储示例
        UserDetails user = User.builder()
                .username(username)
                .password(passwordEncoder().encode(password))
                .roles(role)
                .build();
        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
